package newx.com
{
	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.events.IEventDispatcher;
	import flash.system.ApplicationDomain;
	import flash.utils.Dictionary;
	
	import newx.BaseObject;
	import newx.com.loader.SwfLoader;
	import newx.utils.MemoryOptimise;
	import newx.utils.debug.IO;
	
	public class ResManager extends BaseObject
	{
		private static	var res:ResManager;
		
//		private static var _ResList 		: Dictionary 	= new Dictionary( true );
		
//		/**资源请求线程池*/
//		private var	getListArr	:Array		=	new Array();
//		private var	isGetting	:Boolean	=	false;		
//		private var	getResLoader:Loader;
		
//		/**加载驱动器是否启动*/
//		private var driveIsInit	:Boolean=	false;
		
//		/**
//		 *	缓存资源 
//		 * @param url
//		 * @param res
//		 * 
//		 */
//		public static function SaveRess( url : String, res : *  ):void
//		{
//			_ResList[ url ] = res;
//		}
//		
//		/**
//		 *	通过key获得库元件 
//		 * @param key
//		 * @return 是什么类型就返回什么类型
//		 */
//		public static function GetRess( key : String ) : *
//		{
//			 return _ResList[ key ]
//		}
				
		public function ResManager(target:IEventDispatcher=null)
		{
//			super(target);
			if ( res == null )
	   		{
	   			super(target);
//	   			initLoadDrive()
	   		}
	   		else
	   		{
	   			throw new Error( "ResManager is static!" );
	   		}
		}
				
		public static function getResContentCopy(key:String):DisplayObject
		{
			return copy(getResContent(key));
		}

		/**
		 * 已废弃，用于取出资源原本
		 * @param key
		 * @return 
		 * 
		 */		
		public static function getResContent(key:String):DisplayObject
		{
//			trace("getResContent ------------>>>>>   =  " + key);
			if (res	==	null)
			{
				res	= 	new ResManager();
			}
			
			if(!isResHave(key))
			{
				return null;
			}
			
			var tRes:Object	=	res.GetProperties(key);
			
			if(tRes == null)
			{
				return null;
			}
			return  tRes as DisplayObject;
		}
		
		/**
		 * 加载一系列资源
		 * listArr[i]		:{key:String,url:String}
		 * onLoadComplete	:列表加载完成后的回调
		 * */
		public static function loadResList(listArr:Array,onLoadComplete:Function = null,thisObj:Object = null,onItemFun:Function = null):void
		{
			if (res	==	null)
			{
				res	= 	new ResManager();
			}
			
			var tLength	:uint		=	listArr.length
			var n		:uint		=	0
			var	tKey	:String		=	"";
			var	tUrl	:String		=	"";
			
			var onLoadOver:Function	=	function(...argc):void
			{
				n++;
				if(tLength<=n)
				{
					if(onLoadComplete != null)
					{
						onLoadComplete.call(thisObj);
					}					
				}
				else
				{
					if(onItemFun != null)
					{
						onItemFun.call(thisObj);
					}					
				}				
			}
			
			for(var i:uint = 0 ; i < tLength ; i ++)
			{
				if(listArr[i].hasOwnProperty("key"))
				{
					tKey	=	listArr[i].key
				}
				else
				{
					throw new Error("LoadList have no key Item!");
				}
				
				if(listArr[i].hasOwnProperty("url"))
				{
					tUrl	=	listArr[i].url
				}
				else
				{
					throw new Error("LoadList have no url Item!");
				}
				
				loadRes(tKey,tUrl,onLoadOver);
			}
		}
		
		/**
		 * 加载并缓存资源
		 * 
		 * @param key				：资源ID
		 * @param resPath			：资源加载地址
		 * @param onLoadComplete	：资源加载成功后的回调
		 * @param thisObj			：回调容器
		 * */
		public static function loadRes(key:String,resPath:String,onLoadComplete:Function = null,pList:Array = null):void
		{
			IO.traceLog("ResManager loadRes!");
			
			if (res	==	null)
			{
				res	= 	new ResManager();
			}
						
			if(isResHave(key))
			{
				if( onLoadComplete!= null)
				{
					onLoadComplete(getResContentCopy(key),pList);
				}
				return;
			}
			
			var url		:String	=	resPath;
			//加载堆栈
			var tArray	:Array;
						
			if(!res.CheckProperties("temp"+key))
			{
				//新建1级缓冲
				tArray	=	[];
				res.HandleProperties("temp"+key,tArray);
				tArray.push([onLoadComplete,pList,url])
				
				SwfLoader.StartLoad(url,null,onLoadOver,[null,key,tArray,false]);
			}
			else
			{
				//缓存加载序列
				if(onLoadComplete != null)
				{
					tArray		=	res.GetProperties("temp"+key);
					tArray.push([onLoadComplete,pList,url]);
				}				
			}
		}
		
		/**
		 * 加载资源，且不保存原始应用。
		 * 它同loadRes可以解决当多个加载需求为同一地址时只需要加载一遍。
		 * 不过它不保存原始引用，也就是说，当加载完成后，它不会将原始引用保存在内存中。
		 * */
		public static function loadResNoSave(key:String,resPath:String,onLoadComplete:Function = null,pList:Array = null):void
		{
			
			IO.traceLog("ResManager loadResNoSave!");
			
			if (res	==	null)
			{
				res	= 	new ResManager();
			}
			
			if(isResHave(key))
			{
				if( onLoadComplete!= null)
				{
					onLoadComplete(getResContentCopy(key),pList);
				}
				return;
			}
			
			var url		:String	=	resPath;
			//加载堆栈
			var tArray	:Array;
			
			if(!res.CheckProperties("temp"+key))
			{
				//新建1级缓冲
				tArray	=	[];
				res.HandleProperties("temp"+key,tArray);
				tArray.push([onLoadComplete,pList,url])
				
				SwfLoader.StartLoad(url,null,onLoadOver,[null,key,tArray,true]);
			}
			else
			{
				//缓存加载序列
				if(onLoadComplete != null)
				{
					tArray		=	res.GetProperties("temp"+key);
					tArray.push([onLoadComplete,pList,url]);
				}				
			}
		}
		
//		/**
//		 * 停止正在加载且未加载完的资源
//		 * */
//		public static function stopResLoading():void
//		{
//			var tDeleteKey:Array	=	[];
//			//IO.traceMessage("stopResLoading===========================================");
//			res.getDataForEach(function(keyStr:String, val:*):void
//			{
//				IO.traceMessage("keyStr:",keyStr);
//				if (keyStr.indexOf("temp") > -1)
//				{
//					//要加载的资源地址
//					var tKey:String	=	keyStr.replace("temp", "");
//					
//					//val是相同加载地址的请求队列
//					var tUrl:String	=	val[0][2];
//					
//					tDeleteKey.push(keyStr);
//					
//					SwfLoader.Close(tUrl);
//					
//					if (!res.CheckProperties(tKey) || res.GetProperties(tKey) == null)
//					{
//						IO.traceError("可能出现异步问题。");
//					}
//				}		
//			});
//			
//			var tSize:int	=	tDeleteKey.length;
//			
//			for (var i:int = 0; i < tSize; i++)
//			{
//				deleteRes(tDeleteKey[i]);
//			}
//		}
		
		private static function onLoadOver(val:DisplayObject,pList:Array = null):void
		{
			if(res == null)
			{
				val		=	null;
				pList	=	null;
				return
			}
			
			//pList[0] 是加载进度的处理函数，由StartLoad提供
			var key			:String		=	pList[1];
			var tArray		:Array		=	pList[2];
			var isRemove	:Boolean	=	pList[3];
			
			//停止所有动画
			MemoryOptimise.stopMovie(val as DisplayObjectContainer);
			
			if (!res.CheckProperties("temp" + key))
			{
				return;
			}
			
			if(isRemove)
			{
				//不缓存
				if(val == null)
				{
					IO.traceError("不 缓存资源加载失败。key："+key);
				}
			}
			else
			{
				//缓存
				if(val != null)
				{
					res.HandleProperties("AppDomain__"+key,
						val.loaderInfo.applicationDomain);
					res.HandleProperties(key,val);
				}
				else
				{
//					trace("缓存资源加载失败。key：",key)
					IO.traceError("缓存资源加载失败。key："+key);
				}
			}
			
			//派发同一加载
			var tArr	:Array;
			var tFun	:Function;
			var tList	:Array;
			
			while(tArray.length>0)
			{
				tArr	=	tArray.pop();
				tFun	=	tArr[0];
				tList	=	tArr[1];
				
				if(tFun!=null)
				{
					tFun(val,tList);
				}
			}
			
			//清楚1级缓存
			res.DeleteProperties("temp"+key);
		}
		
//		public static function newResClassAndToBitMapData(
//			className:String):BitmapData
//		{
//			var tDisView	:DisplayObject	=	newResClass(className);
//			var bmd			:BitmapData		=	null;
//			if(tDisView != null)
//			{
//				bmd	=	new BitmapData(tDisView.width,tDisView.height,true,0xFFFFFFFF);
//				bmd.draw(tDisView);
//			}
//			
//			return bmd;
//			
//		}
		
		public static function newResClass(className:String):DisplayObject
		{
//			var tData:Date	=	new Date();
//			var times:uint	=	0;
			
//			IO.traceLog("newResClass"," 当前内存：",System.totalMemory * 0.000000954);
			if(className == "" || className == null)
			{
				return null;
			}
			
//			trace("newResClass ------------>>>>>   =  " + className);
			
			if (res	==	null)
			{
				res	= 	new ResManager();
			}
			
			else
			{
				if(className.indexOf(".") > 0 )
				{
					return null
				}
				var cla			:Object			=	null;				
				var tRes		:Object;
//				var tLoadInfo	:LoaderInfo;
				var appDomain:ApplicationDomain
//				try
//				{
				for(var p:String in res.Properties)
				{
					tRes	=	res.Properties[p];
					if(tRes != null && tRes is ApplicationDomain)
					{
						appDomain	=	tRes as ApplicationDomain;
						
						if(appDomain.hasDefinition(className))
						{
							cla		=	appDomain.getDefinition(className) as Class;
							
							var mc : DisplayObject = new cla() as DisplayObject;
							
//							if( mc is MovieClip )
//							{
//								MovieClip(mc).stop();s
//							}
//							
							return	mc;
						}
					}
				}
			}
			
			return null;
		}
		
		public static function SaveUISkin(val:DisplayObject):void
		{
			if (res	==	null)
			{
				res	= 	new ResManager();
			}
			
			res.HandleProperties("UISkin",val);
			res.HandleProperties("AppDomain__UISkin",val.loaderInfo.applicationDomain);
		}
		
		/**
		 * 缓存一个加载资源
		 * */
		public static function SaveRes(key:String,val:DisplayObject):void
		{
			if (res	==	null)
			{
				res	= 	new ResManager();
			}
			
			res.HandleProperties(key,val);
			res.HandleProperties("AppDomain__"+key,val.loaderInfo.applicationDomain);
			
			IO.traceLog("ResManager SaveRes!");
		}
		
		/**
		 * 简单复制
		 * @param val		要复制的mc
		 * @param isLoaded	被复制对象是否加载过，如果未被加载过则不能使用二进制复制法
		 * @return 
		 * 
		 */		
//		public static function copy(val:Object,isLoaded:Boolean = false,space:DisplayObjectContainer = null,complete:Function = null):DisplayObject
		public static function copy(val:Object):DisplayObject
		{	
			if(val == null)
			{
				return null;
			}
//			trace("copy ------------>>>>>   =  " + val);
			
//			IO.traceLog("copy"," 当前内存：",System.totalMemory * 0.000000954);
			
//			if(isLoaded)
//			{
//				if(space != null)
//				{
//					copyResInTo((val as DisplayObject),space,complete);					
//				}				
//			}
//			else
//			{
			if(val is Bitmap)
			{
				return new Bitmap((val as Bitmap).bitmapData);
			}
			else
			{	
				var cls : Class = val.constructor
				return new cls();
			}
			return null;
		}
		
//		/**
//		 * 复制mc到新对象中
//		 *  
//		 * @param mc			：待复制的mc
//		 * @param space			：目标对象容器
//		 * @param onReturnMcFun	：回调函数（添加完成时触发）
//		 * @param target		：回调容器
//		 * 
//		 */		
//		public static function copyResInTo(mc:DisplayObject,space:DisplayObjectContainer,complete:Function = null):void
//		{
//			var newMC:DisplayObject;
//			
//			if(mc == null || !(mc is DisplayObject))
//			{
//				return;
//			}
//			
//			var onAddToSpace	:Function	=	function(e:Event):void
//			{
//				if(complete!=null)
//				{
//					complete.(newMC)
//					newMC.removeEventListener(Event.ADDED_TO_STAGE,onAddToSpace);
//				}
//			}
//			
//			if(mc is Bitmap)
//			{
//				newMC	=	new Bitmap((mc as Bitmap).bitmapData);
//				newMC.addEventListener(Event.ADDED_TO_STAGE,onAddToSpace);
//				space.addChild(newMC);
//			}
//			else
//			{
//				var onLoadOver		:Function	=	function(e:Event):void
//				{
//					newMC	=	e.target.content as DisplayObject;
//					newMC.addEventListener(Event.ADDED_TO_STAGE,onAddToSpace);
//					space.addChild(newMC);
//					tLoader.removeEventListener(Event.COMPLETE,onLoadOver);
//				}				
//				var tLoader	:Loader		=	new Loader()
//				tLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoadOver)
//				var tBr:ByteArray	=	(mc as MovieClip).loaderInfo.bytes;
//				tLoader.loadBytes(tBr);
//			}
//		}
		
		/**
		 * 判断资源是否缓存
		 * @param key
		 * 
		 */		
		public static function isResHave(key:String):Boolean
		{
			if (res	==	null)
			{
				res	=	new ResManager();
				return false;
			}
			
			if(key == null || key == "")
			{
				return false;
			}
			
			return res.CheckProperties(key);
		}
		
		public static function clearAllRes():void
		{
			if (res	==	null)
			{
				new ResManager();
				return;
			}
			
			res.getDataForEach(function(key:String,val:*):void
			{
				if(val is DisplayObject)
				{
					freeRes(val);
				}
			});
			
			res.Properties	=	null;
			res	=	null;
		}
		
		/**
		 * 回收显示对象 
		 * @param data
		 * 
		 */		
		public static function freeRes(data:Object):void
		{
			var val:DisplayObject	=	data as DisplayObject;
			
			if(val == null)
			{
				return;
			}
			
			if(val as DisplayObjectContainer != null)
				MemoryOptimise.stopMovie(val as DisplayObjectContainer);
			
			if(val.parent != null)
			{
				val.parent.removeChild(val);
			}
			
			if(val is Bitmap)
			{
				(val as Bitmap).bitmapData.dispose();
			}
		}
		
		/**
		 * 删除资源缓存
		 *  
		 * @param key	资源ID
		 * 
		 */		
		public static function deleteRes(key:String):void
		{
			if (res	==	null)
			{
				new ResManager();
				return;
			}
			
			if(key == null || key == "")
			{
				return;
			}
			
			if(res.CheckProperties(key))
			{
				freeRes(res.GetProperties(key))
				res.DeleteProperties(key);
			}
			
			if(res.CheckProperties("temp"+key))
			{
				freeRes(res.GetProperties("temp"+key))
				res.DeleteProperties("temp"+key);
			}
		}
	}
}